package com.bantang.template;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import com.bantang.model.SandBoxParam;
import com.bantang.model.SandBoxVO;
import com.bantang.utils.CompileCodeUtil;
import com.bantang.utils.ExecResult;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 代码沙箱抽象类模板
 */
public abstract class CodeSandBoxTemplate {

    protected SandBoxVO sandBoxVO = new SandBoxVO();

    protected String userCodePath;

    public SandBoxVO exec(SandBoxParam sandBoxParam) {

        File fileAndWriter = createFileAndWriter(sandBoxParam);
        ExecResult compileResult = CompileCode(fileAndWriter);
        if (!"success".equals(compileResult.getMessage())) {
            sandBoxVO.setBoxMessage("编译错误");
            return sandBoxVO;
        }
        System.out.println("编译后");
        System.out.println(compileResult);
        System.out.println(compileResult.getMessage());

        runCode(sandBoxParam);
        packagingResult(sandBoxVO);

        return sandBoxVO;
    }

    /**
     * 1. 创建隔离文件夹并写入Solve.java文件
     *
     * @param sandBoxParam
     * @return
     */
    protected File createFileAndWriter(SandBoxParam sandBoxParam) {

        //获取代码 输入用例
        String code = sandBoxParam.getCode();
        List<String> input = sandBoxParam.getInput();

        //获取项目根路径
        String userDir = System.getProperty("user.dir");
        //在根目录创建文件夹
        String codePathName = userDir + File.separator + "tempCode";
        if (!FileUtil.exist(codePathName)) {
            FileUtil.mkdir("tempCode");
        }
        //把用户代码隔离 写入新的文件夹 Main.java
        userCodePath = codePathName + File.separator + UUID.randomUUID();
        String userCodePathName = userCodePath + File.separator + "Solve.java";
        return FileUtil.writeString(code, userCodePathName, StandardCharsets.UTF_8);
    }

    /**
     * 2. 编译Solve.java 生成 Solve.class 文件
     *
     * @param userFile
     * @return
     */
    protected ExecResult CompileCode(File userFile) {
        String codeCmd = String.format("javac -encoding utf-8 %s", userFile.getAbsolutePath());
        return CompileCodeUtil.compileCode(codeCmd);
    }

    /**
     * 运行代码获取 包装输出结果
     *
     * @return
     */
    public abstract SandBoxVO runCode(SandBoxParam sandBoxParam);

    /**
     * 删除文件夹
     */
    protected SandBoxVO packagingResult(SandBoxVO sandBoxVO) {
        System.out.println("整理结果 删除文件 停止容器");
        FileUtil.del(userCodePath);
        return sandBoxVO;
    }

}
